/*-
 * Copyright (c) 2009 Paulo Vizcaíno
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <iostream>
#include "video.h"

#define FATAL_ERROR   std::cout << "FAILURE" << std::endl; \
            std::cerr << SDL_GetError() << std::endl; \
            return false;

namespace Video
{

    SDL_Surface *back = NULL;
    int start_ticks = 0, end_ticks = 0;
    SDL_Rect rect;

    unsigned long nextTicks = 0, frames = 0;
    char stringBuffer[255];

    Uint32 black;

    bool init_video(int x, int y, int bpp)
    {
        std::cout << "Setting up screen... ";
		
		if (SDL_Init(SDL_INIT_VIDEO)) 
		{
            FATAL_ERROR
		}

        back = SDL_SetVideoMode(x, y, bpp, SDL_SWSURFACE | SDL_DOUBLEBUF);
        if (back == NULL)
        {
            std::cout << "FAILURE" << std::endl;
            std::cerr << SDL_GetError() << std::endl;
            return false;
        }
        std::cout << "OK" << std::endl;

        black = SDL_MapRGB(back->format, 0, 0, 0);
        
        

        // Everything OK
        return true;
    }

    bool refresh()
    {
        if (SDL_Flip(back) < 0)
        {
            std::cerr << SDL_GetError() << std::endl;
            return false;
        }

        // Refreshed OK
        return true;
    }

    bool blit(Sprite *sprite)
    {
        rect.x = sprite->get_x();
        rect.y = sprite->get_y();

        if (SDL_BlitSurface(sprite->get_actual_frame()->get_surface(), NULL, back, &rect) < 0)
        {
            std::cerr << SDL_GetError() << std::endl;
            return false;
        }

        return true;
    }
    
    void set_start_ticks() {
        start_ticks = SDL_GetTicks(); 
    }

    void regulate_fps()
    {
        end_ticks = SDL_GetTicks() - start_ticks;
        if (end_ticks < DIV_FPS)
        {
            SDL_Delay(DIV_FPS - end_ticks);
        }
    }
    
    char out_of_bounds(Sprite *sprite) 
    {
        char tmp = 0;
        int x = sprite->get_x();
        int y = sprite->get_y();
        /* 0000 No collision
         * 0001 Up
         * 0010 Down
         * 0100 Left
         * 1000 Right
         */
        if ( (sprite->get_width()+x) >= back->w ) tmp |= A_RIGHT;
        if ( (sprite->get_height()+y) >= back->h ) tmp |= A_DOWN;
        if ( x <= 0 ) tmp |= A_LEFT;
        if ( y <= 0 ) tmp |= A_UP;
        
        return tmp;
    }
    
    void shutdown() 
    {
        SDL_FreeSurface(back);
        SDL_Quit();
    }

    bool clear_screen()
    {
        if (SDL_FillRect(back, NULL, black) < 0)
        {
            std::cerr << SDL_GetError() << std::endl;
            return false;
        }

        return true;

    }
} // Close namespace Video
